﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;

namespace CD2WebAudio3Lib
{
    public class my_settings : IDisposable
    {
        private bool m_Disposed = false;
        private string m_FileName;
        private bool m_Changed = false;
        private XmlDocument m_Doc = null;

        public enum SettingsType { User, Machine };

        public my_settings(SettingsType pType, string pCompanyName, string pApplicationName)
        {
            // name of settings file
            m_FileName = get_File_Name(pType, pCompanyName, pApplicationName);

            // create if it does not exist yet
            if (!File.Exists(m_FileName)) create_New_File();

            // now load the file
            m_Doc = new XmlDocument();
            m_Doc.Load(m_FileName);

        }

        private string get_File_Name(SettingsType pType, string pCompanyName, string pApplicationName)
        {
            string dirName = string.Empty;
            if (pType == SettingsType.User)
            {
                dirName = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            }
            else
            {
                dirName = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
            }

            if (!dirName.EndsWith("\\")) dirName += "\\";

            if ((pCompanyName != null) && (pCompanyName.Length > 0))
            {
                dirName += pCompanyName + "\\";
            }

            if ((pApplicationName != null) && (pApplicationName.Length > 0))
            {
                dirName += pApplicationName + "\\";
            }

            if (pType == SettingsType.User)
            {
                return dirName + "UserSettings.config";
            }
            else
            {
                return dirName + "AppSettings.config";
            }
        }

        private void create_New_File()
        {
            XmlDocument doc = new XmlDocument();

            // root element
            doc.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
                "<configuration>" +
                "</configuration>");

            // sections
            doc.DocumentElement.AppendChild(doc.CreateNode(XmlNodeType.Element, "connectionStrings", ""));

            // check for directory
            FileInfo fi = new FileInfo(m_FileName);
            if (!Directory.Exists(fi.DirectoryName))
            {
                Directory.CreateDirectory(fi.DirectoryName);
            }

            // write to disk
            doc.Save(m_FileName);
        }

        public XmlNode Get_Section(string pSectionName)
        {
            foreach (XmlNode node in m_Doc.DocumentElement.ChildNodes)
            {
                if (node.Name.CompareTo(pSectionName) == 0)
                {
                    return node;
                }
            }

            return null;

        }

        public string Get_String_Setting(string pSectionName, string pSettingName)
        {
            
            XmlNode section = Get_Section(pSectionName);

            // check for missing section
            if (section == null) return null;

            foreach (XmlNode node in section.ChildNodes)
            {
                if (node.Name.CompareTo(pSettingName) == 0)
                {
                    return node.Attributes.GetNamedItem("value").Value;
                }
            }

            // if you are here, it was not found
            return null;
            
        }

        public string Get_String_Setting(string pSectionName, string pSettingName, string pDefault)
        {

            string s = Get_String_Setting(pSectionName, pSettingName);

            if (s == null) return pDefault; else return s;

        }

        public decimal Get_Numeric_Setting(string pSectionName, string pSettingName)
        {
            string tempVal = Get_String_Setting(pSectionName, pSettingName);

            if (tempVal == null)
                return (decimal)0;
            else
                return decimal.Parse(tempVal);
        }

        public void Set_String_Setting(string pSectionName, string pSettingName, string pValue)
        {
            XmlNode section = Get_Section(pSectionName);
            bool exists = false;

            // check for missing section
            if (section == null)
            {
                section = m_Doc.DocumentElement.AppendChild(m_Doc.CreateNode(XmlNodeType.Element, pSectionName, ""));
            }

            // set the value, if it exists
            foreach (XmlNode node in section.ChildNodes)
            {
                if (node.Name.CompareTo(pSettingName) == 0)
                {
                    exists = true;
                    m_Changed = true;

                    bool nodeExists = false;
                    foreach (XmlNode attr in node.Attributes)
                    {
                        if (attr.Name.CompareTo("value") == 0)
                        {
                            nodeExists = true;
                            attr.Value = pValue;
                        }
                    }

                    if (!nodeExists)
                    {
                        XmlNode attr = m_Doc.CreateNode(XmlNodeType.Attribute, "value", "");
                        attr.Value = pValue;
                        node.Attributes.SetNamedItem(attr);
                    }
                }
            }

            // add the setting if not found
            if (!exists)
            {
                XmlNode node = section.AppendChild(m_Doc.CreateNode(XmlNodeType.Element, pSettingName, ""));
                XmlNode attr = m_Doc.CreateNode(XmlNodeType.Attribute, "value", "");
                attr.Value = pValue;
                node.Attributes.SetNamedItem(attr);

                m_Changed = true;
            }

        }

        public void Set_Numeric_Setting(string pSectionName, string pSettingName, decimal pValue)
        {
            Set_String_Setting(pSectionName, pSettingName, pValue.ToString());
        }

        public void Save()
        {
            if (m_Changed)
            {
                m_Doc.Save(m_FileName);

                m_Changed = false;
            }
        }
    
        void IDisposable.Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected void Dispose(bool pDisposing)
        {
            if (!m_Disposed)
            {
                if (pDisposing)
                {
                    // code for managed objects
                }

                Save();
            }
            m_Disposed = true;
        }

    }
}
